package com.imy.common.view.slidetab;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.GradientDrawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.imy.common.R;
import com.imy.common.view.slidetab.listener.OnTabListener;
import com.imy.common.view.slidetab.utils.UnreadMsgUtils;
import com.imy.common.view.slidetab.widget.MsgTextView;

import java.util.ArrayList;
import java.util.Collections;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

/** 滑动TabLayout,对于ViewPager的依赖性强
 * 样式参考https://blog.csdn.net/poorkick/article/details/70215672
 * */
public class SlidingTabLayout extends HorizontalScrollView
    implements ViewPager.OnPageChangeListener {
  protected Context mContext;
  protected ViewPager mViewPager;
  protected ArrayList<String> mTitles;
  protected LinearLayout mTabsContainer;
  protected int mCurrentTab;
  private float mCurrentPositionOffset;
  protected int mTabCount;
  /** 用于绘制显示器 */
  private Rect mIndicatorRect = new Rect();
  /** 用于实现滚动居中 */
  private Rect mTabRect = new Rect();
  private GradientDrawable mIndicatorDrawable = new GradientDrawable();

  private Paint mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  private Paint mDividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  private Paint mTrianglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  private Path mTrianglePath = new Path();
  private static final int STYLE_NORMAL = 0;
  private static final int STYLE_TRIANGLE = 1;
  private static final int STYLE_BLOCK = 2;
  private int mIndicatorStyle = STYLE_NORMAL;

  protected float mTabPadding;
  protected boolean mTabSpaceEqual;
  protected float mTabWidth;

  /** indicator */
  private int mIndicatorColor;
  private float mIndicatorHeight;
  private float mIndicatorWidth;
  private float mIndicatorCornerRadius;
  private float mIndicatorMarginLeft;
  private float mIndicatorMarginTop;
  private float mIndicatorMarginRight;
  private float mIndicatorMarginBottom;
  private int mIndicatorGravity;
  private boolean mIndicatorWidthEqualTitle;

  /** underline */
  private int mUnderlineColor;
  private float mUnderlineHeight;
  private int mUnderlineGravity;

  /** divider */
  private int mDividerColor;
  private float mDividerWidth;
  private float mDividerPadding;

  /** title */
  public static final int TEXT_BOLD_NONE = 0;
  public static final int TEXT_BOLD_WHEN_SELECT = 1;
  public static final int TEXT_BOLD_BOTH = 2;
  protected float mTextsize;
  protected float mUnselectedTextsize;
  protected int mTextSelectColor;
  protected int mTextUnselectColor;
  protected int mTextBold;
  protected boolean mTextAllCaps;

  private int mLastScrollX;
  private int mHeight;
  private boolean mSnapOnTabClick;

  public SlidingTabLayout(Context context) {
    this(context, null, 0);
  }

  public SlidingTabLayout(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public SlidingTabLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    setFillViewport(true);//设置滚动视图是否可以伸缩其内容以填充视口
    setWillNotDraw(false);//重写onDraw方法,需要调用这个方法来清除flag
    setClipChildren(false);
    setClipToPadding(false);

    this.mContext = context;
    mTabsContainer = new LinearLayout(context);
    addView(mTabsContainer);

    obtainAttributes(context, attrs);

    //get layout_height
    String height = attrs.getAttributeValue("http://schemas.android.com/apk/res/android",
        "layout_height");

    if (height.equals(ViewGroup.LayoutParams.MATCH_PARENT + "")) {
    } else if (height.equals(ViewGroup.LayoutParams.WRAP_CONTENT + "")) {
    } else {
      int[] systemAttrs = { android.R.attr.layout_height };
      TypedArray a = context.obtainStyledAttributes(attrs, systemAttrs);
      mHeight = a.getDimensionPixelSize(0, ViewGroup.LayoutParams.WRAP_CONTENT);
      a.recycle();
    }
  }

  protected void obtainAttributes(Context context, AttributeSet attrs) {
    TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingTabLayout);

    mIndicatorStyle = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_style, STYLE_NORMAL);
    mIndicatorColor = ta.getColor(R.styleable.SlidingTabLayout_tl_indicator_color,
        Color.parseColor(mIndicatorStyle == STYLE_BLOCK ? "#4B6A87" : "#ffffff"));
    mIndicatorHeight = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_height,
        dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 4 : (mIndicatorStyle == STYLE_BLOCK ? -1 : 2)));
    mIndicatorWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_width,
        dp2px(mIndicatorStyle == STYLE_TRIANGLE ? 10 : -1));
    mIndicatorCornerRadius = ta.getDimension(
        R.styleable.SlidingTabLayout_tl_indicator_corner_radius,
        dp2px(mIndicatorStyle == STYLE_BLOCK ? -1 : 0));
    mIndicatorMarginLeft = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_left,
        dp2px(0));
    mIndicatorMarginTop = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_top,
        dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
    mIndicatorMarginRight = ta.getDimension(R.styleable.SlidingTabLayout_tl_indicator_margin_right,
        dp2px(0));
    mIndicatorMarginBottom = ta.getDimension(
        R.styleable.SlidingTabLayout_tl_indicator_margin_bottom,
        dp2px(mIndicatorStyle == STYLE_BLOCK ? 7 : 0));
    mIndicatorGravity = ta.getInt(R.styleable.SlidingTabLayout_tl_indicator_gravity,
        Gravity.BOTTOM);
    mIndicatorWidthEqualTitle = ta.getBoolean(
        R.styleable.SlidingTabLayout_tl_indicator_width_equal_title, false);

    mUnderlineColor = ta.getColor(R.styleable.SlidingTabLayout_tl_underline_color,
        Color.parseColor("#ffffff"));
    mUnderlineHeight = ta.getDimension(R.styleable.SlidingTabLayout_tl_underline_height, dp2px(0));
    mUnderlineGravity = ta.getInt(R.styleable.SlidingTabLayout_tl_underline_gravity,
        Gravity.BOTTOM);

    mDividerColor = ta.getColor(R.styleable.SlidingTabLayout_tl_divider_color,
        Color.parseColor("#ffffff"));
    mDividerWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_divider_width, dp2px(0));
    mDividerPadding = ta.getDimension(R.styleable.SlidingTabLayout_tl_divider_padding, dp2px(12));

    mTextsize = ta.getDimension(R.styleable.SlidingTabLayout_tl_textsize, sp2px(14));
    mUnselectedTextsize = ta.getDimension(R.styleable.SlidingTabLayout_tl_unselectedtextsize, mTextsize);
    mTextSelectColor = ta.getColor(R.styleable.SlidingTabLayout_tl_textSelectColor,
        Color.parseColor("#ffffff"));
    mTextUnselectColor = ta.getColor(R.styleable.SlidingTabLayout_tl_textUnselectColor,
        Color.parseColor("#AAffffff"));
    mTextBold = ta.getInt(R.styleable.SlidingTabLayout_tl_textBold, TEXT_BOLD_NONE);
    mTextAllCaps = ta.getBoolean(R.styleable.SlidingTabLayout_tl_textAllCaps, false);

    mTabSpaceEqual = ta.getBoolean(R.styleable.SlidingTabLayout_tl_tab_space_equal, false);
    mTabWidth = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_width, dp2px(-1));
    mTabPadding = ta.getDimension(R.styleable.SlidingTabLayout_tl_tab_padding,
        mTabSpaceEqual || mTabWidth > 0 ? dp2px(0) : dp2px(20));

    customTabView(ta);
  }

  protected void customTabView(TypedArray ta){
    ta.recycle();
  }
  /** 关联ViewPager */
  public void setViewPager(ViewPager vp) {
    if (vp == null || vp.getAdapter() == null) {
      throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
    }

    this.mViewPager = vp;

    this.mViewPager.removeOnPageChangeListener(this);
    this.mViewPager.addOnPageChangeListener(this);
    notifyDataSetChanged();
  }

  /** 关联ViewPager,用于不想在ViewPager适配器中设置titles数据的情况 */
  public void setViewPager(ViewPager vp, String[] titles) {
    if (vp == null || vp.getAdapter() == null) {
      throw new IllegalStateException("ViewPager or ViewPager adapter can not be NULL !");
    }

    if (titles == null || titles.length == 0) {
      throw new IllegalStateException("Titles can not be EMPTY !");
    }

    if (titles.length != vp.getAdapter().getCount()) {
      throw new IllegalStateException("Titles length must be the same as the page count !");
    }

    this.mViewPager = vp;
    mTitles = new ArrayList<>();
    Collections.addAll(mTitles, titles);

    this.mViewPager.removeOnPageChangeListener(this);
    this.mViewPager.addOnPageChangeListener(this);
    notifyDataSetChanged();
  }

  /** 关联ViewPager,用于连适配器都不想自己实例化的情况 */
  public void setViewPager(ViewPager vp, String[] titles, FragmentActivity fa,
      ArrayList<Fragment> fragments) {
    if (vp == null) {
      throw new IllegalStateException("ViewPager can not be NULL !");
    }

    if (titles == null || titles.length == 0) {
      throw new IllegalStateException("Titles can not be EMPTY !");
    }

    this.mViewPager = vp;
    this.mViewPager.setAdapter(
        new InnerPagerAdapter(fa.getSupportFragmentManager(), fragments, titles));

    this.mViewPager.removeOnPageChangeListener(this);
    this.mViewPager.addOnPageChangeListener(this);
    notifyDataSetChanged();
  }

  /** 更新数据 */
  public void notifyDataSetChanged() {
    mTabsContainer.removeAllViews();
    this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();
    View tabView;
    for (int i = 0; i < mTabCount; i++) {
      tabView = View.inflate(mContext, R.layout.layout_tab, null);
      CharSequence pageTitle =
          mTitles == null ? mViewPager.getAdapter().getPageTitle(i) : mTitles.get(i);
      addTab(i, pageTitle.toString(), tabView);
    }

    updateTabStyles();
  }

  public void addNewTab(String title) {
    View tabView = View.inflate(mContext, R.layout.layout_tab, null);
    if (mTitles != null) {
      mTitles.add(title);
    }

    CharSequence pageTitle =
        mTitles == null ? mViewPager.getAdapter().getPageTitle(mTabCount) : mTitles.get(mTabCount);
    addTab(mTabCount, pageTitle.toString(), tabView);
    this.mTabCount = mTitles == null ? mViewPager.getAdapter().getCount() : mTitles.size();

    updateTabStyles();
  }

  /** 创建并添加tab */
  protected void addTab(final int position, String title, View tabView) {
    TextView tv_tab_title = (TextView) tabView.findViewById(R.id.tv_tab_title);
    if (tv_tab_title != null) {
      if (title != null) {
        tv_tab_title.setText(title);
      }
    }

    tabView.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        onTabClick(v);
      }
    });

    /** 每一个Tab的布局参数 */
    LinearLayout.LayoutParams lp_tab = mTabSpaceEqual ?
        new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f) :
        new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
    if (mTabWidth > 0) {
      lp_tab = new LinearLayout.LayoutParams((int) mTabWidth, LayoutParams.MATCH_PARENT);
    }

    mTabsContainer.addView(tabView, position, lp_tab);
  }


  /**
   *
   * 点击Tab抽离出一个方法、为了被继承重写
   * by mahuaheng 2018/10/26
   * @param v
   */
  protected void onTabClick(View v){
    int position = mTabsContainer.indexOfChild(v);
    if (position != -1) {
      if (mViewPager.getCurrentItem() != position) {
        if (mSnapOnTabClick) {
          mViewPager.setCurrentItem(position, false);
        } else {
          mViewPager.setCurrentItem(position);
        }
        //上面mViewPager.setCurrentItem 已经有onTabSelect 回调了、这里不需要重复
       /* if (mListener != null) {
          mListener.onTabSelect(position);
        }*/
      } else {
        if (mListener != null) {
          mListener.onTabReselect(position);
        }
      }
    }
  }

  protected void updateTabStyles() {
    for (int i = 0; i < mTabCount; i++) {
      View v = mTabsContainer.getChildAt(i);
      v.setPadding((int) mTabPadding, v.getPaddingTop(), (int) mTabPadding, v.getPaddingBottom());
      TextView tv_tab_title = (TextView) v.findViewById(R.id.tv_tab_title);
      if (tv_tab_title != null) {
        tv_tab_title.setTextColor(i == mCurrentTab ? mTextSelectColor : mTextUnselectColor);
        //tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextsize);
        tv_tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, i == mCurrentTab ? mTextsize : mUnselectedTextsize);
        if (mTextAllCaps) {
          tv_tab_title.setText(tv_tab_title.getText().toString().toUpperCase());
        }

        if (mTextBold == TEXT_BOLD_BOTH || (mTextBold == TEXT_BOLD_WHEN_SELECT && i == mCurrentTab)) {//当前选中也要粗体 by_mahuaheng 2019/9/12
          tv_tab_title.getPaint().setFakeBoldText(true);
        } else if (mTextBold == TEXT_BOLD_NONE) {
          tv_tab_title.getPaint().setFakeBoldText(false);
        }
      }
    }
  }

  @Override
  public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    /**
     * position:当前View的位置
     * mCurrentPositionOffset:当前View的偏移量比例.[0,1)
     */
    this.mCurrentTab = position;
    this.mCurrentPositionOffset = positionOffset;
    scrollToCurrentTab();
    invalidate();
  }

  @Override
  public void onPageSelected(int position) {
    updateTabSelection(position);

    // 增加联动事件（viewPager翻页触发onTabSelect）
    // 洪顺利 2018-03-21
    if (mListener != null) {
      mListener.onTabSelect(position);
    }
  }

  @Override
  public void onPageScrollStateChanged(int state) {
  }

  /** HorizontalScrollView滚到当前tab,并且居中显示 */
  private void scrollToCurrentTab() {
    if (mTabCount <= 0) {
      return;
    }

    int offset = (int) (mCurrentPositionOffset * mTabsContainer.getChildAt(mCurrentTab).getWidth());
    /**当前Tab的left+当前Tab的Width乘以positionOffset*/
    int newScrollX = mTabsContainer.getChildAt(mCurrentTab).getLeft() + offset;

    if (mCurrentTab > 0 || offset > 0) {
      /**HorizontalScrollView移动到当前tab,并居中*/
      newScrollX -= getWidth() / 2 - getPaddingLeft();
      calcIndicatorRect();
      newScrollX += ((mTabRect.right - mTabRect.left) / 2);
    }

    if (newScrollX != mLastScrollX) {
      mLastScrollX = newScrollX;
      /** scrollTo（int x,int y）:x,y代表的不是坐标点,而是偏移量
       *  x:表示离起始位置的x水平方向的偏移量
       *  y:表示离起始位置的y垂直方向的偏移量
       */
      scrollTo(newScrollX, 0);
    }
  }

  protected void updateTabSelection(int position) {
    for (int i = 0; i < mTabCount; ++i) {
      View tabView = mTabsContainer.getChildAt(i);
      final boolean isSelect = i == position;
      TextView tab_title = tabView.findViewById(R.id.tv_tab_title);

      if (tab_title != null) {
        tab_title.setTextColor(isSelect ? mTextSelectColor : mTextUnselectColor);
        tab_title.setTextSize(TypedValue.COMPLEX_UNIT_PX, i == position ? mTextsize : mUnselectedTextsize);
        if (mTextBold == TEXT_BOLD_WHEN_SELECT) {
          tab_title.getPaint().setFakeBoldText(isSelect);
        }
      }
    }
  }

  private float margin;

  private void calcIndicatorRect() {
    View currentTabView = mTabsContainer.getChildAt(this.mCurrentTab);
    float left = currentTabView.getLeft();
    float right = currentTabView.getRight();

    //for mIndicatorWidthEqualTitle
    if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
      TextView tab_title = (TextView) currentTabView.findViewById(R.id.tv_tab_title);
      mTextPaint.setTextSize(mTextsize);
      float textWidth = mTextPaint.measureText(tab_title.getText().toString());
      margin = (right - left - textWidth) / 2;
    }

    if (this.mCurrentTab < mTabCount - 1) {
      View nextTabView = mTabsContainer.getChildAt(this.mCurrentTab + 1);
      float nextTabLeft = nextTabView.getLeft();
      float nextTabRight = nextTabView.getRight();

      left = left + mCurrentPositionOffset * (nextTabLeft - left);
      right = right + mCurrentPositionOffset * (nextTabRight - right);

      //for mIndicatorWidthEqualTitle
      if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
        TextView next_tab_title = nextTabView.findViewById(R.id.tv_tab_title);
        mTextPaint.setTextSize(mUnselectedTextsize);
        float nextTextWidth = mTextPaint.measureText(next_tab_title.getText().toString());
        float nextMargin = (nextTabRight - nextTabLeft - nextTextWidth) / 2;
        margin = margin + mCurrentPositionOffset * (nextMargin - margin);
      }
    }

    mIndicatorRect.left = (int) left;
    mIndicatorRect.right = (int) right;
    //for mIndicatorWidthEqualTitle
    if (mIndicatorStyle == STYLE_NORMAL && mIndicatorWidthEqualTitle) {
      mIndicatorRect.left = (int) (left + margin - 1);
      mIndicatorRect.right = (int) (right - margin - 1);
    }

    mTabRect.left = (int) left;
    mTabRect.right = (int) right;

    if (mIndicatorWidth < 0) {   //indicatorWidth小于0时,原jpardogo's PagerSlidingTabStrip

    } else {//indicatorWidth大于0时,圆角矩形以及三角形
      float indicatorLeft =
          currentTabView.getLeft() + (currentTabView.getWidth() - mIndicatorWidth) / 2;

      if (this.mCurrentTab < mTabCount - 1) {
        View nextTab = mTabsContainer.getChildAt(this.mCurrentTab + 1);
        indicatorLeft = indicatorLeft + mCurrentPositionOffset * (currentTabView.getWidth() / 2
            + nextTab.getWidth() / 2);
      }

      mIndicatorRect.left = (int) indicatorLeft;
      mIndicatorRect.right = (int) (mIndicatorRect.left + mIndicatorWidth);
    }
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if (isInEditMode() || mTabCount <= 0) {
      return;
    }

    int height = getHeight();
    int paddingLeft = getPaddingLeft();
    // draw divider
    if (mDividerWidth > 0) {
      mDividerPaint.setStrokeWidth(mDividerWidth);
      mDividerPaint.setColor(mDividerColor);
      for (int i = 0; i < mTabCount - 1; i++) {
        View tab = mTabsContainer.getChildAt(i);
        canvas.drawLine(paddingLeft + tab.getRight(), mDividerPadding, paddingLeft + tab.getRight(),
            height - mDividerPadding, mDividerPaint);
      }
    }

    // draw underline
    if (mUnderlineHeight > 0) {
      mRectPaint.setColor(mUnderlineColor);
      if (mUnderlineGravity == Gravity.BOTTOM) {
        canvas.drawRect(paddingLeft, height - mUnderlineHeight,
            mTabsContainer.getWidth() + paddingLeft, height, mRectPaint);
      } else {
        canvas.drawRect(paddingLeft, 0, mTabsContainer.getWidth() + paddingLeft, mUnderlineHeight,
            mRectPaint);
      }
    }

    //draw indicator line

    calcIndicatorRect();
    if (mIndicatorStyle == STYLE_TRIANGLE) {
      if (mIndicatorHeight > 0) {
        mTrianglePaint.setColor(mIndicatorColor);
        mTrianglePath.reset();
        mTrianglePath.moveTo(paddingLeft + mIndicatorRect.left, height);
        mTrianglePath.lineTo(paddingLeft + mIndicatorRect.left / 2 + mIndicatorRect.right / 2,
            height - mIndicatorHeight);
        mTrianglePath.lineTo(paddingLeft + mIndicatorRect.right, height);
        mTrianglePath.close();
        canvas.drawPath(mTrianglePath, mTrianglePaint);
      }
    } else if (mIndicatorStyle == STYLE_BLOCK) {
      if (mIndicatorHeight < 0) {
        mIndicatorHeight = height - mIndicatorMarginTop - mIndicatorMarginBottom;
      } else {

      }

      if (mIndicatorHeight > 0) {
        if (mIndicatorCornerRadius < 0 || mIndicatorCornerRadius > mIndicatorHeight / 2) {
          mIndicatorCornerRadius = mIndicatorHeight / 2;
        }

        mIndicatorDrawable.setColor(mIndicatorColor);
        mIndicatorDrawable.setBounds(paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
            (int) mIndicatorMarginTop,
            (int) (paddingLeft + mIndicatorRect.right - mIndicatorMarginRight),
            (int) (mIndicatorMarginTop + mIndicatorHeight));
        mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
        mIndicatorDrawable.draw(canvas);
      }
    } else {
               /* mRectPaint.setColor(mIndicatorColor);
                calcIndicatorRect();
                canvas.drawRect(getPaddingLeft() + mIndicatorRect.left, getHeight() - mIndicatorHeight,
                        mIndicatorRect.right + getPaddingLeft(), getHeight(), mRectPaint);*/

      if (mIndicatorHeight > 0) {
        mIndicatorDrawable.setColor(mIndicatorColor);

        if (mIndicatorGravity == Gravity.BOTTOM) {
          mIndicatorDrawable.setBounds(
              paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
              height - (int) mIndicatorHeight - (int) mIndicatorMarginBottom,
              paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
              height - (int) mIndicatorMarginBottom);
        } else {
          mIndicatorDrawable.setBounds(
              paddingLeft + (int) mIndicatorMarginLeft + mIndicatorRect.left,
              (int) mIndicatorMarginTop,
              paddingLeft + mIndicatorRect.right - (int) mIndicatorMarginRight,
              (int) mIndicatorHeight + (int) mIndicatorMarginTop);
        }
        mIndicatorDrawable.setCornerRadius(mIndicatorCornerRadius);
        mIndicatorDrawable.draw(canvas);
      }
    }
  }

  //setter and getter
  public void setCurrentTab(int currentTab) {
    this.mCurrentTab = currentTab;
    mViewPager.setCurrentItem(currentTab);

  }

  public void setCurrentTab(int currentTab, boolean smoothScroll) {
    this.mCurrentTab = currentTab;
    mViewPager.setCurrentItem(currentTab, smoothScroll);
  }

  public void setIndicatorStyle(int indicatorStyle) {
    this.mIndicatorStyle = indicatorStyle;
    invalidate();
  }

  public void setTabPadding(float tabPadding) {
    this.mTabPadding = dp2px(tabPadding);
    updateTabStyles();
  }

  public void setTabSpaceEqual(boolean tabSpaceEqual) {
    this.mTabSpaceEqual = tabSpaceEqual;
    updateTabStyles();
  }

  public void setTabWidth(float tabWidth) {
    this.mTabWidth = dp2px(tabWidth);
    updateTabStyles();
  }

  public void setIndicatorColor(int indicatorColor) {
    this.mIndicatorColor = indicatorColor;
    invalidate();
  }

  public void setIndicatorHeight(float indicatorHeight) {
    this.mIndicatorHeight = dp2px(indicatorHeight);
    invalidate();
  }

  public void setIndicatorWidth(float indicatorWidth) {
    this.mIndicatorWidth = dp2px(indicatorWidth);
    invalidate();
  }

  public void setIndicatorCornerRadius(float indicatorCornerRadius) {
    this.mIndicatorCornerRadius = dp2px(indicatorCornerRadius);
    invalidate();
  }

  public void setIndicatorGravity(int indicatorGravity) {
    this.mIndicatorGravity = indicatorGravity;
    invalidate();
  }

  public void setIndicatorMargin(float indicatorMarginLeft, float indicatorMarginTop,
      float indicatorMarginRight, float indicatorMarginBottom) {
    this.mIndicatorMarginLeft = dp2px(indicatorMarginLeft);
    this.mIndicatorMarginTop = dp2px(indicatorMarginTop);
    this.mIndicatorMarginRight = dp2px(indicatorMarginRight);
    this.mIndicatorMarginBottom = dp2px(indicatorMarginBottom);
    invalidate();
  }

  public void setIndicatorWidthEqualTitle(boolean indicatorWidthEqualTitle) {
    this.mIndicatorWidthEqualTitle = indicatorWidthEqualTitle;
    invalidate();
  }

  public void setUnderlineColor(int underlineColor) {
    this.mUnderlineColor = underlineColor;
    invalidate();
  }

  public void setUnderlineHeight(float underlineHeight) {
    this.mUnderlineHeight = dp2px(underlineHeight);
    invalidate();
  }

  public void setUnderlineGravity(int underlineGravity) {
    this.mUnderlineGravity = underlineGravity;
    invalidate();
  }

  public void setDividerColor(int dividerColor) {
    this.mDividerColor = dividerColor;
    invalidate();
  }

  public void setDividerWidth(float dividerWidth) {
    this.mDividerWidth = dp2px(dividerWidth);
    invalidate();
  }

  public void setDividerPadding(float dividerPadding) {
    this.mDividerPadding = dp2px(dividerPadding);
    invalidate();
  }

  public void setTextsize(float textsize) {
    this.mTextsize = sp2px(textsize);
    updateTabStyles();
  }

  public void setTextSelectColor(int textSelectColor) {
    this.mTextSelectColor = textSelectColor;
    updateTabStyles();
  }

  public void setTextUnselectColor(int textUnselectColor) {
    this.mTextUnselectColor = textUnselectColor;
    updateTabStyles();
  }

  public void setTextBold(int textBold) {
    this.mTextBold = textBold;
    updateTabStyles();
  }

  public void setTextAllCaps(boolean textAllCaps) {
    this.mTextAllCaps = textAllCaps;
    updateTabStyles();
  }

  public void setSnapOnTabClick(boolean snapOnTabClick) {
    mSnapOnTabClick = snapOnTabClick;
  }

  public int getTabCount() {
    return mTabCount;
  }

  public int getCurrentTab() {
    return mCurrentTab;
  }

  public int getIndicatorStyle() {
    return mIndicatorStyle;
  }

  public float getTabPadding() {
    return mTabPadding;
  }

  public boolean isTabSpaceEqual() {
    return mTabSpaceEqual;
  }

  public float getTabWidth() {
    return mTabWidth;
  }

  public int getIndicatorColor() {
    return mIndicatorColor;
  }

  public float getIndicatorHeight() {
    return mIndicatorHeight;
  }

  public float getIndicatorWidth() {
    return mIndicatorWidth;
  }

  public float getIndicatorCornerRadius() {
    return mIndicatorCornerRadius;
  }

  public float getIndicatorMarginLeft() {
    return mIndicatorMarginLeft;
  }

  public float getIndicatorMarginTop() {
    return mIndicatorMarginTop;
  }

  public float getIndicatorMarginRight() {
    return mIndicatorMarginRight;
  }

  public float getIndicatorMarginBottom() {
    return mIndicatorMarginBottom;
  }

  public int getUnderlineColor() {
    return mUnderlineColor;
  }

  public float getUnderlineHeight() {
    return mUnderlineHeight;
  }

  public int getDividerColor() {
    return mDividerColor;
  }

  public float getDividerWidth() {
    return mDividerWidth;
  }

  public float getDividerPadding() {
    return mDividerPadding;
  }

  public float getTextsize() {
    return mTextsize;
  }

  public int getTextSelectColor() {
    return mTextSelectColor;
  }

  public int getTextUnselectColor() {
    return mTextUnselectColor;
  }

  public int getTextBold() {
    return mTextBold;
  }

  public boolean isTextAllCaps() {
    return mTextAllCaps;
  }

  public TextView getTitleView(int tab) {
    View tabView = mTabsContainer.getChildAt(tab);
    return tabView.findViewById(R.id.tv_tab_title);
  }

  //setter and getter

  // show MsgTipView
  private Paint mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  protected SparseArray<Boolean> mInitSetMap = new SparseArray<>();

  /**
   * 显示未读消息
   *
   * @param position 显示tab位置
   * @param num num小于等于0显示红点,num大于0显示数字
   */
  public MsgTextView showMsg(int position, int num) {
    if (position >= mTabCount) {
      position = mTabCount - 1;
    }

    View tabView = mTabsContainer.getChildAt(position);
    MsgTextView tipView = tabView.findViewById(R.id.rtv_msg_tip);
    if (tipView != null) {
      UnreadMsgUtils.show(tipView, num);

      if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
        return tipView;
      }

      setMsgMargin(position, 4, 2);
      mInitSetMap.put(position, true);
    }
    return tipView;
  }

  /**
   * 有些msg是显示 xx万，传入字符串则直接展示、没必要转换成99+的样式
   * @param position
   * @param num
   * @return
   */
  public MsgTextView showMsg(int position, String num) {
    if (position >= mTabCount) {
      position = mTabCount - 1;
    }

    View tabView = mTabsContainer.getChildAt(position);
    MsgTextView tipView = tabView.findViewById(R.id.rtv_msg_tip);
    if (tipView != null) {

      tipView.setVisibility(View.VISIBLE);
      tipView.setText(num);

      if (mInitSetMap.get(position) != null && mInitSetMap.get(position)) {
        return tipView;
      }

      setMsgMargin(position, 3, 0);
      mInitSetMap.put(position, true);
    }

    return tipView;
  }

  /**
   * 显示未读红点
   *
   * @param position 显示tab位置
   */
  public void showDot(int position) {
    if (position >= mTabCount) {
      position = mTabCount - 1;
    }
    showMsg(position, 0);
  }

  /** 隐藏未读消息 */
  public void hideMsg(int position) {
    if (position >= mTabCount) {
      position = mTabCount - 1;
    }

    View tabView = mTabsContainer.getChildAt(position);
    MsgTextView tipView = tabView.findViewById(R.id.rtv_msg_tip);
    if (tipView != null) {
      tipView.setVisibility(View.GONE);
    }
  }

  /** 设置未读消息偏移,原点为文字的右上角.当控件高度固定,消息提示位置易控制,显示效果佳 */
  public void setMsgMargin(int position,final float leftPadding, final float bottomPadding) {
    if (position >= mTabCount) {
      position = mTabCount - 1;
    }
    final View tabView = mTabsContainer.getChildAt(position);
    final MsgTextView tipView = tabView.findViewById(R.id.rtv_msg_tip);
    if (tipView != null) {
      TextView tv_tab_title = tabView.findViewById(R.id.tv_tab_title);
      mTextPaint.setTextSize(position == mCurrentTab ? mTextsize : mUnselectedTextsize);
      //mTextPaint.setTextSize(mTextsize);
      final float textWidth = mTextPaint.measureText(tv_tab_title.getText().toString());
      final float textHeight = mTextPaint.descent() - mTextPaint.ascent();
      tipView.setVisibility(INVISIBLE);
      tabView.postDelayed(new Runnable() { //延时暂时是为了getMeasuredWidth 能正常获取到值
        @Override
        public void run() {  //延时一会为了getMeasuredWidth 能得到值
          tipView.setVisibility(VISIBLE);
          MarginLayoutParams lp = (MarginLayoutParams) tipView.getLayoutParams();
          lp.leftMargin = mTabWidth >= 0 ? (int) (mTabWidth / 2 + textWidth / 2 + dp2px(leftPadding))
              : (int) (tabView.getMeasuredWidth()/2 + textWidth/2 + dp2px(leftPadding));
          lp.topMargin = mHeight > 0 ? (int) (mHeight - textHeight) / 2 - dp2px(bottomPadding) : 0;
          tipView.setLayoutParams(lp);
        }
      },80);

    }
  }

  /** 当前类只提供了少许设置未读消息属性的方法,可以通过该方法获取MsgView对象从而各种设置 */
  public MsgTextView getMsgView(int position) {
    if (position >= mTabCount) {
      position = mTabCount - 1;
    }
    View tabView = mTabsContainer.getChildAt(position);
    return tabView.findViewById(R.id.rtv_msg_tip);
  }

  private OnTabListener mListener;

  public void setOnTabSelectListener(OnTabListener listener) {
    this.mListener = listener;
  }

  class InnerPagerAdapter extends FragmentPagerAdapter {
    private ArrayList<Fragment> fragments = new ArrayList<>();
    private String[] titles;

    public InnerPagerAdapter(FragmentManager fm, ArrayList<Fragment> fragments, String[] titles) {
      super(fm);
      this.fragments = fragments;
      this.titles = titles;
    }

    @Override
    public int getCount() {
      return fragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
      return titles[position];
    }

    @Override
    public Fragment getItem(int position) {
      return fragments.get(position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
      // 覆写destroyItem并且空实现,这样每个Fragment中的视图就不会被销毁
      // super.destroyItem(container, position, object);
    }

    @Override
    public int getItemPosition(Object object) {
      return PagerAdapter.POSITION_NONE;
    }
  }

  @Override
  protected Parcelable onSaveInstanceState() {
    Bundle bundle = new Bundle();
    bundle.putParcelable("instanceState", super.onSaveInstanceState());
    bundle.putInt("mCurrentTab", mCurrentTab);
    return bundle;
  }

  @Override
  protected void onRestoreInstanceState(Parcelable state) {
    if (state instanceof Bundle) {
      Bundle bundle = (Bundle) state;
      mCurrentTab = bundle.getInt("mCurrentTab");
      state = bundle.getParcelable("instanceState");
      if (mCurrentTab != 0 && mTabsContainer.getChildCount() > 0) {
        updateTabSelection(mCurrentTab);
        scrollToCurrentTab();
      }
    }
    super.onRestoreInstanceState(state);
  }

  protected int dp2px(float dp) {
    final float scale = mContext.getResources().getDisplayMetrics().density;
    return (int) (dp * scale + 0.5f);
  }

  protected int sp2px(float sp) {
    final float scale = this.mContext.getResources().getDisplayMetrics().scaledDensity;
    return (int) (sp * scale + 0.5f);
  }
}
